﻿using System.Linq;
using System.Reflection;

namespace ForceSystem.Untangler
{
    /// <summary>
    /// This class provide on-demand cache mechanism.
    /// </summary>
    public class UntangledAssembly
    {
        public UntangledTypeCollection      Types { get { return _types; } }
        public UntangledNamespaceCollection Namespaces { get { return _namespaces; } }

        public UntangledAssembly(UntangledContext context, string filename)
        {
            _context = context;
            _assembly = _loader.ReflectionOnlyLoad(filename);
            ParseAssembly();
        }

        void ParseAssembly()
        {
            // Parse type information.
            var untangledTypes = (from type in _assembly.GetTypes()
                       where type.IsPublic
                       orderby type.FullName
                       select new UntangledType(_context, this, type)).ToArray();

            _types = UntangledTypeCollection.FromEnumeable(untangledTypes);

            // Generate namespace collection from types.
            var namespaces =  from ns in 
                            ( from type in untangledTypes
                                group type by type.Namespace into n
                                orderby n.Key
                                select n
                            )
                            select new UntangledNamespace(ns.Key, ns.ToList());

            _namespaces = UntangledNamespaceCollection.FromEnumerable(namespaces);
        }

        readonly AssemblyLoader _loader = new AssemblyLoader();
        private readonly UntangledContext _context;
        private readonly Assembly _assembly;

        UntangledTypeCollection _types;
        UntangledNamespaceCollection    _namespaces;
    }
}
